package com.party.jackclientandroid.controller;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.model.ObjectMetadata;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.facebook.stetho.server.http.HttpStatus;
import com.party.jackclientandroid.BaseActivity;
import com.party.jackclientandroid.api.BaseApi;
import com.party.jackclientandroid.BaseActivityTitle;
import com.party.jackclientandroid.bean.BaseResult;
import com.party.jackclientandroid.bean.OSSConfig;
import com.party.jackclientandroid.okhttp.RetrofitRxClient;
import com.party.jackclientandroid.utils.FileNameUtils;
import com.party.jackclientandroid.utils.SignUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.xiaosai.imagecompress.utils.BitmapUtil;


/**
 * <a href="https://blog.csdn.net/qq_29534541/article/details/81867571">android 修改头像后并上传到阿里云</a><br>
 * Created by tangxuebing on 2018/5/18.
 */

public class AliyunOSSController extends BaseController {
    public final static String OSS_BANNER = "1";
    public final static String OSS_APP_THEME = "2";
    public final static String OSS_USER_QRCODE = "3";
    public final static String OSS_USER_IMG = "4";
    public final static String OSS_SHOP_QRCODE = "5";
    public final static String OSS_SHOP_IMG = "6";
    public final static String OSS_SHOP_EVN = "7";
    public final static String OSS_SHOP_GOODS = "8";
    public final static String OSS_GROUP_BUY = "9";
    public final static String OSS_LICENSE = "10";
    /**
     * 压缩之后的图片路径
     */
    private File targetDir;
    private String targetDirName = "A_Jackseller";
    // 表示压缩之后的最大图片大小,单位为kb
    private int maxSize = 1024;
    private OSSClient ossClient;
    private OSSConfig ossConfig;

    public AliyunOSSController(BaseActivity baseActivity) {
        super(baseActivity);
        targetDir = new File(Environment.getExternalStorageDirectory(), targetDirName);
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }
    }

    public Observable<BaseResult<OSSConfig>> getOssConfig(String type) {
        Map<String, String> signData = getSignData();
        signData.put("id", type);
        Observable<BaseResult<OSSConfig>> observable = getObservable().getOssConfig(getSign(signData), signData);
        return observable;
    }

    public void initOssConfig(OSSConfig ossConfig, Context context) {
        this.ossConfig = ossConfig;
        setOssConfig(ossConfig, context);
    }

    private void setOssConfig(OSSConfig ossConfig, Context context) {
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时，默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时，默认15秒
        conf.setMaxConcurrentRequest(8); // 最大并发请求数，默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
        ossClient = new OSSClient(context, "http://" + ossConfig.getEndpoint(), credentialProvider, conf);
    }

    public BaseApi getObservable() {
        return RetrofitRxClient.INSTANCE
                .getRetrofit()
                .create(BaseApi.class);
    }

    /**
     * 基本参数的容器
     *
     * @return
     */
    public Map<String, String> getSignData() {
        Map map = new HashMap();
        map.put("token", mApplication.getToken());
        return map;
    }

    public String getSign(Map data) {
        return SignUtils.getSign(data);
    }

    private String checkSuffix(String path) {
        if (TextUtils.isEmpty(path) || !path.contains(".")) {
            return ".jpg";
        }
        return path.substring(path.lastIndexOf("."), path.length());
    }

    private String getImageCacheFile(String suffix) {
        return targetDir + "/" +
                System.currentTimeMillis() +
                (int) (Math.random() * 1000) +
                (TextUtils.isEmpty(suffix) ? ".jpg" : suffix);
    }

    /**
     * 使用同步压缩方式
     *
     * @param filePaths
     */
    private Observable<List<String>> compressPictures(List<String> filePaths) {
        return Observable
                .just(filePaths)
                .subscribeOn(Schedulers.io())
                .concatMap(new Function<List<String>, ObservableSource<List<String>>>() {
                    @Override
                    public ObservableSource<List<String>> apply(@NonNull List<String> list) throws Exception {
                        return Observable.just(compressPicturesSync(list));
                    }
                });
    }

    public Observable<String> uploadPicturesSync(String u_s_id, String filePaths, boolean deletePicture) {
        List<String> data = new ArrayList<>();
        data.add(filePaths);
        return uploadPicturesSync(u_s_id, data, deletePicture);
    }

    /**
     * 阿里云异步上传图片
     *
     * @param filePaths
     * @param needDeletePicture 上传之后是否需要删除本地压缩保存的图片
     * @return
     */
    public Observable<String> uploadPicturesSync(final String u_s_id, List<String> filePaths, final boolean needDeletePicture) {
        //ToastUtils.t(mApplication,"filePaths:"+filePaths.size());
        return compressPictures(filePaths)
                .concatMap(new Function<List<String>, ObservableSource<List<String>>>() {
                    @Override
                    public ObservableSource<List<String>> apply(@NonNull List<String> list) throws Exception {
                        List<String> tempList = new ArrayList<>();
                        for (String str : list) {
                            // 如果已经是阿里云图片地址
                            if (str.contains("http")) {
                                tempList.add(str);
                                continue;
                            }
                            String ossPath = getOssPath(u_s_id, FileNameUtils.getSuffix(str));
                            String uploadPictureSync = uploadPictureSync(ossPath, str);
                            if (uploadPictureSync != null) {
                                tempList.add(uploadPictureSync);
                            }
                        }
                        if (needDeletePicture) {
                            for (String str : list) {
                                File file = new File(str);
                                if (file.exists()) {
                                    file.delete();
                                }
                            }
                        }
                        return Observable.just(tempList);
                    }
                })
                .concatMap(new Function<List<String>, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(@NonNull List<String> list) throws Exception {
                        StringBuilder sb = new StringBuilder();
                        int size = list.size();
                        for (int i = 0; i < size; i++) {
                            if (i != 0) {
                                sb.append(",");
                            }
                            // 如果已经是阿里云图片地址
                            String str = list.get(i);
                            if (str.contains("https://")) {
                                sb.append(str);
                            } else {
                                sb.append("https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + File.separator + str);
                            }
                        }
                        return Observable.just(sb.toString());
                    }
                });
    }

    public String getOssPath(String user_or_shop_id, String suffix) {
        if (ossConfig.getAddress().endsWith("/")) {
            return ossConfig.getAddress() + user_or_shop_id + "_" + System.currentTimeMillis() + suffix;
        }
        return ossConfig.getAddress() + File.separator + user_or_shop_id + "_" + System.currentTimeMillis() + suffix;
    }

    /**
     * 阿里云同步上传图片
     *
     * @param filePaths
     * @return
     */
    public String uploadPictureSync(String serviceImgPath, String filePaths) {
        try {
            ObjectMetadata objectMeta = new ObjectMetadata();
            objectMeta.setContentType("image/jpeg");
            PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), serviceImgPath, filePaths);
            putObjectRequest.setMetadata(objectMeta);
            PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
            int statusCode = putObjectResult.getStatusCode();
            if (statusCode != HttpStatus.HTTP_OK) {
                return null;
            }
            return serviceImgPath;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用同步压缩方式
     *
     * @param filePaths
     */
    private List<String> compressPicturesSync(List<String> filePaths) {
        List<String> list = new ArrayList<>();
        for (String filePath : filePaths) {
            // 图片地址为null或者"",不进行压缩和添加
            if (TextUtils.isEmpty(filePath)) continue;
            // 如果路径是网络数据则不压缩
            if (filePath.contains("http://")) {
                list.add(filePath);
                continue;
            }
            String picture = compressPictureSync(filePath);
            if (picture != null) {
                list.add(picture);
            }
        }
        return list;
    }


    /**
     * 使用同步压缩方式
     *
     * @param filePath
     * @return
     */
    public String compressPictureSync(String filePath) {
        try {
            String targetCompressPath = getImageCacheFile(checkSuffix(filePath));
            String resultStr = BitmapUtil.compressBitmap(filePath, targetCompressPath, maxSize);
            if ("1".equals(resultStr)) {
                return targetCompressPath;
            } else {
                Log.e("compress", "onError==resultStr:" + resultStr);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("compress", "onError==msg:" + e.getMessage());
        }
        return null;
    }
}

